package com.sq.partner.manager.common;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.log4j.Logger;

import com.sq.partner.manager.common.exception.AppException;
import com.sq.partner.manager.dao.impl.BaseDaoImpl;
import com.sq.partner.manager.mybatis.model.DictDto;
import com.sq.partner.manager.util.ApplicationContextUtil;
import com.sq.partner.manager.util.LogUtil;
import com.sq.partner.manager.util.StrUtil;

/**
 * 交易系统字典表缓存
 * @author sankun
 *
 */
public class DictCache {
	private static Logger logger = LogUtil.getLog(DictCache.class);
	private static Map<String,List<DictDto>> cacheMap = new HashMap<String,List<DictDto>>();;
	
	/**
	 * 
	 * @param codeType
	 * @return
	 */
	public static List<DictDto> getDict(String codeType){
		List<DictDto> list = cacheMap.get(codeType);
		if(list == null){
			logger.debug(codeType + "字典信息为空，从数据库中加载");
			try{
				list = getFromDb(codeType,null);
				synchronized (cacheMap) {
					cacheMap.put(codeType, list);
				}
			}catch(Exception e){
				logger.error("从数据库中加载字典信息失败",e);
			}
		}
		return list;
	}
	
	public static void refreshCache(){
		synchronized (cacheMap) {
			cacheMap.clear();
		}
	}
	
	/**
	 * 获取字典表中的产品类型信息，因此信息取法较为特殊（只取子产品），故专门新增一个方完戏
	 * @param parentType 1 人险 2财险
	 * @return
	 */
	public static List<DictDto> getProdType(String parentType){
		List<DictDto> list = cacheMap.get(Constants.DICT_PROD_TYPE + parentType);
		if(StrUtil.isEmpty(parentType)){
			return null;
		}
		if(!parentType.matches("\\w+")){
			logger.error("非法的parentType:"+parentType);
			return null;
		}
		
		if(list == null){
			logger.debug(Constants.DICT_PROD_TYPE + "字典信息为空，从数据库中加载");
			try{
				String sql = "select code_type,code,code_name,other_code,other_code2,code2_name,other_name from t_gateway_dict where code_type = ?  and parent_code = '"+parentType+"' order by sort_no,code ";
				list = getFromDb(Constants.DICT_PROD_TYPE,sql);
				synchronized (cacheMap) {
					cacheMap.put(Constants.DICT_PROD_TYPE  + parentType, list);
				}
			}catch(Exception e){
				logger.error("从数据库中加载字典信息失败",e);
			}
		}
		return list;
	}


	/**
	 * 获取字典表中的产品类型信息，且仅选择以headCore开头的产品
	 * @param parentType 1 人险 2财险
	 * @return
	 */
	public static List<DictDto> getProdTypeAndHeadCore(String parentType,String headCore){
		List<DictDto> list = cacheMap.get(Constants.DICT_PROD_TYPE + parentType + ":" + headCore);
		if(StrUtil.isEmpty(parentType) || StrUtil.isEmpty(headCore)){
			return null;
		}
		if(!parentType.matches("\\w+") || !headCore.matches("\\w+")){
			logger.error("非法的parentType:"+parentType + "或非法的headCore:" + headCore);
			return null;
		}
		if(list == null){
			logger.debug(Constants.DICT_PROD_TYPE + "字典信息为空，从数据库中加载");
			try{
				String sql = "select code_type,code,code_name,other_code,other_code2,code2_name,other_name from t_gateway_dict where code_type = ?  and code_status='1' and parent_code = '"+parentType+"'  and code like '"+ headCore +"%' order by sort_no,code ";
				list = getFromDb(Constants.DICT_PROD_TYPE,sql);
				synchronized (cacheMap) {
					cacheMap.put(Constants.DICT_PROD_TYPE  + parentType + ":" + headCore, list);
				}
			}catch(Exception e){
				logger.error("从数据库中加载字典信息失败",e);
			}
		}
		return list;
	}
	
		/**
		 * 查询 字典表信息 无数据返回null
		 * @param codeType
		 * @return
		 * @throws AppException
		 * @throws SQLException
		 */
		private static List<DictDto> getFromDb(String codeType,String sql) throws AppException, SQLException{
			if(StrUtil.isEmpty(codeType)){return null;}
			DataSource ds = (DataSource)ApplicationContextUtil.getBean("dataSource");
			if(ds == null){
				throw new AppException("无法获取数据源:"+ ds);
			}
			Connection conn = null;
			PreparedStatement pstmt = null;
			ResultSet rs = null;
			List<DictDto> list = null;
			if(StrUtil.isEmpty(sql)){
				sql = "select code_type,code,code_name,other_code,other_code2,code2_name,other_name from t_gateway_dict where code_type = ? order by sort_no,code ";
			}
			try{
				conn = ds.getConnection();
				pstmt = conn.prepareStatement(sql);
				pstmt.setString(1, codeType);
				rs = pstmt.executeQuery();
				while (rs.next()){
					if(list == null){
						list = new ArrayList<DictDto>();
					}
					DictDto dd = new DictDto();
					dd.setCodeType(rs.getString("code_type"));
					dd.setCode(rs.getString("code"));
					dd.setCodeName(rs.getString("code_name"));
					dd.setOtherCode(rs.getString("other_code"));
					dd.setOtherName(rs.getString("other_name"));
					dd.setOtherCode2(rs.getString("other_code2"));
					dd.setCode2Name(rs.getString("code2_name"));
					list.add(dd);
				}
			}catch(Exception e){
		      logger.error("从数据库中加载字典信息失败",e);
	        }finally{
				BaseDaoImpl.close(rs);
				BaseDaoImpl.close(pstmt);
				BaseDaoImpl.close(conn);
			}
			return list;
		}
		
		
	/**
	 * 字典表根据父编码查询子集的数据
	 */
	public static List<DictDto> getDictDataByParentCode(String codeType,
			String parentCode) {
		List<DictDto> list = cacheMap.get(codeType + parentCode);
		if (StrUtil.isEmpty(codeType)) {
			return null;
		}
		if (!"codeType".matches("\\w+")) {
			logger.error("非法的codeType:" + codeType);
			return null;
		}
		if (!"parentCode".matches("\\w+")) {
			logger.error("非法的parentCode:" + parentCode);
			return null;
		}
		if (list == null) {
			logger.debug(codeType + "字典信息为空，从数据库中加载");
			try {
				String sql = "select code_type,code,code_name,other_code,other_code2,code2_name,other_name from t_gateway_dict where code_type = ?  and parent_code = '"
						+ parentCode + "' order by sort_no,code ";
				list = getFromDb(codeType, sql);
				synchronized (cacheMap) {
					cacheMap.put(codeType + parentCode, list);
				}
			} catch (Exception e) {
				logger.error("从数据库中加载字典信息失败", e);
			}
		}
		return list;
	}
	
	/**
	 * 自定义sql
	 * @param codeType
	 * @return
	 */
	public static List<DictDto> getDict1(String codeType,String sql){
		List<DictDto> list = null;
			try{
				list = getFromDb1(codeType,sql);
				synchronized (cacheMap) {
					cacheMap.put(codeType, list);
				}
			}catch(Exception e){
				logger.error("从数据库中加载字典信息失败",e);
			}

		return list;
	}
	
	/**
	 * 查询 外部传sql
	 * @param codeType
	 * @return
	 * @throws AppException
	 * @throws SQLException
	 */
	private static List<DictDto> getFromDb1(String codeType,String sql) throws AppException, SQLException{
		if(StrUtil.isEmpty(codeType)){return null;}
		DataSource ds = (DataSource)ApplicationContextUtil.getBean("dataSource");
		if(ds == null){
			throw new AppException("无法获取数据源:"+ ds);
		}
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		List<DictDto> list = null;
		try{
			conn = ds.getConnection();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			while (rs.next()){
				if(list == null){
					list = new ArrayList<DictDto>();
				}
				DictDto dd = new DictDto();
				dd.setCodeType(rs.getString("code_type"));
				dd.setCode(rs.getString("code"));
				dd.setCodeName(rs.getString("code_name"));
				dd.setParentCode(rs.getString("parent_code"));
				dd.setOtherCode(rs.getString("other_code"));
				list.add(dd);
			}
		}finally{
			BaseDaoImpl.close(rs);
			BaseDaoImpl.close(pstmt);
			BaseDaoImpl.close(conn);
		}
		return list;
	}
	
//20230509 增加一个查询有效性的方法
	 public static boolean statusCheck(String codeType,String code){
		if(StrUtil.isEmpty(code) || StrUtil.isEmpty(codeType)){
			return true ;
		}
		List<DictDto> dicts = DictCache.getDict(codeType);
		if("new_business_source".equals(codeType)){
			//codeType为new_bussiness_source时 ，有效性个根据otherName 判断，0为停用；1为有效
			for(DictDto dict : dicts){
				if(dict.getCode().equals(code)){
					if(dict.getOtherName().equals("0")){
						return false ;
					}else {
						return true ;
					}	
				}	
			}
		}
		//其他情况默认有效；
		return true ;
	 }
	//20230509增加处理，部分业务来源停用
	public static List<DictDto> remakeNewBussinessSource(){
		List<DictDto> dicts = DictCache.getDict("new_business_source");
		List<DictDto> newBSListIndex = new ArrayList<DictDto>();
		for(DictDto dict : dicts){
			if(dict.getOtherName().equals("0")){
				if( ! dict.getCodeName().endsWith("(已停用)")){
					dict.setCodeName(dict.getCodeName() + "(已停用)");
				}
				newBSListIndex.add(dict);
			}else {
				newBSListIndex.add(dict);
			}
		}
		dicts = newBSListIndex;
		return dicts ;
	}
	//20230509增加处理，部分业务来源停用 (有参)
		public static List<DictDto> remakeNewBussinessSource(List<DictDto> dicts){
			
			List<DictDto> newBSListIndex = new ArrayList<DictDto>();
			for(DictDto dict : dicts){
				if(dict.getOtherName().equals("0")){
					if( ! dict.getCodeName().endsWith("(已停用)")){
						dict.setCodeName(dict.getCodeName() + "(已停用)");
					}
					newBSListIndex.add(dict);
				}else {
					newBSListIndex.add(dict);
				}
			}
			dicts = newBSListIndex;
			return dicts ;
		}
}
